home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 2 / MacMania 2.toast / Demo's / Tools&Utilities / Programming / MSTPChart / Periodic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-26  |  7.9 KB  |  234 lines  |  [TEXT/KAHL]

  1. #include    "MST_Defines.h"
  2. #include    "MST_Externs.h"
  3. #include    "MST_Prototypes.h"
  4.  
  5.  
  6. /*_____________________________________________________________________________
  7.                         Close_PeriodicChart()- close our Periodic Chart window
  8. _____________________________________________________________________________*/
  9.  
  10.  
  11. void    Close_PeriodicChart    ()
  12. {
  13. /*
  14. •        See comments for Close_AboutMST() in the file About.c
  15. */
  16.     if    (PeriodicChartDlog==NIL)    return;
  17.     DisposDialog        (PeriodicChartDlog);
  18.     PeriodicChartDlog    =    NIL;
  19. }
  20.  
  21.  
  22. /*_____________________________________________________________________________
  23.                         Open_PeriodicChart()- create and display our Periodic Chart window
  24. _____________________________________________________________________________*/
  25.  
  26.  
  27. void    Open_PeriodicChart    ()
  28. {
  29. /*
  30. •        See comments for Open_AboutMST() in the file About.c.
  31. */
  32.     if    (PeriodicChartDlog!=NIL)    {    SelectWindow    (PeriodicChartDlog);    return;    }
  33.  
  34.     PeriodicChartDlog = GetNewDialog (ResID_PeriodicChart, NIL, (WindowPtr)-1);
  35.     
  36.     ShowWindow        (PeriodicChartDlog);         
  37. }
  38.  
  39.  
  40. /*_____________________________________________________________________________
  41.                         Update_PeriodicChart()- update our Periodic Chart window
  42. _____________________________________________________________________________*/
  43.  
  44.  
  45. void    UpDate_PeriodicChart()
  46. {
  47.     GDHandle    saveDevice;
  48.     CGrafPtr    saveCGrafPtr;
  49.     int            loop1;
  50.     Str255        thisString;
  51.         
  52.     if    (PeriodicChartDlog==NIL)    return;        /*Make sure the periodic chart window exists*/
  53. /*
  54. •        Now save the current Grafport and set the current port to our Periodic Chart window.
  55. */
  56.     
  57.     GetGWorld    (&saveCGrafPtr,&saveDevice);
  58.     SetGWorld    ((CGrafPtr)PeriodicChartDlog,saveDevice);
  59. /*
  60. •        Now we begin updating. You MUST call BeginUpdate() just before
  61. •        and EndUpdate() just after doing your drawing. These two calls
  62. •        restrict your drawing to just that portion of the window that
  63. •        needs updating, and resets the window's update region to empty,
  64. •        thus clearing the window's update event.
  65. •        Note: Dialogs, which are merely windows with a little more data added
  66. •        to their struct, actually have their own routines for handling
  67. •        updates, activate events, etc. Which ones are available depends
  68. •        upon the type of dialog (alert, modal, or modeless). Here we treat
  69. •        dialogs just like windows.
  70. */
  71.  
  72.     BeginUpdate    (PeriodicChartDlog);
  73. /*
  74. •        Here we set the port's pen colors. A more sophisticated program would examine
  75. •        the operating system version upon initialization and adapt itself to the
  76. •        operating systems capabilities (color Quickdraw might not be available, for
  77. •        example. The program would also survey the available monitors upon initialization,
  78. •        and adjust itself accordingly. For example, the program would not attempt to
  79. •        draw in Light Blue on a monochrome monitor, as it will not show up.
  80. •        If you intend to run this on a monochrome monitor, just substitute Color_Black
  81. •        for every instance of Color_LtBlue in this update routine.
  82. */
  83.     RGBForeColor    (&Color_LtBlue);    /*Set the port's pen colors*/
  84.     RGBBackColor    (&Color_White);
  85. /*
  86. •        Draw our decorative dotted line around the chart
  87. */
  88.     for    (loop1=13;loop1<=PeriodicChartDlog->portRect.right-13;loop1+=2)
  89.     {
  90.         MoveTo    (loop1,PeriodicChartDlog->portRect.top+13);
  91.         Line    (0,0);
  92.         
  93.         MoveTo    (loop1,PeriodicChartDlog->portRect.bottom-13);
  94.         Line    (0,0);
  95.     }
  96.     for    (loop1=13;loop1<=PeriodicChartDlog->portRect.bottom-13;loop1+=2)
  97.     {
  98.         MoveTo    (PeriodicChartDlog->portRect.left+13,    loop1);
  99.         Line    (0,0);
  100.         
  101.         MoveTo    (PeriodicChartDlog->portRect.right-13,    loop1);
  102.         Line    (0,0);
  103.     }
  104. /*
  105. •        Since our program isn't sophisticated enough to allow user selection of fonts,
  106. •        we had better pick one we can rely on being present. That restricts us to
  107. •        Chicago, Geneva, or Monoco.
  108. */
  109.     TextFont    (geneva);
  110.     TextSize    (9);
  111. /*
  112. •        And now we draw each box and write the symbol in it. We've already calculated
  113. •        the rectangles for the boxes, and we have stored the element symbols in a
  114. •        STR# resource. FrameRect draws the rectangle using the current pen. The MoveTo
  115. •        and Move lines just calculate where to position the pen to start writing the
  116. •        element's symbol. The Toolbox call DrawString actually writes the text using
  117. •        the current font, color, etc. Remember, the color, pen size, font, & etc are
  118. •        all properties of the current port. Most QuickDraw commands such as FrameRect,
  119. •        MoveTo, DrawString, & etc operate implicitly on the current port with the
  120. •        current port's settings.
  121. */
  122.     for    (loop1=1;loop1<=Max_NumElements;loop1++)
  123.     {
  124.         RGBForeColor    (&Color_LtBlue);
  125.         FrameRect        (&PeriodicRects[loop1]);
  126.         RGBForeColor    (&Color_Black);
  127.         GetIndString    (thisString,ChemSymbsStr,loop1);
  128.         MoveTo            ((PeriodicRects[loop1].left)/2+(PeriodicRects[loop1].right) /2,
  129.                          (PeriodicRects[loop1].top) /2+(PeriodicRects[loop1].bottom)/2);
  130.         Move            (-StringWidth(thisString)/2,5);
  131.         DrawString        (thisString);        
  132.     }
  133. /*
  134. •        Now we set the port's properties to a few defaults before we leave. In more
  135. •        complex applications, with multiple fonts drawn into a single port, this
  136. •        practice could save us some headaches in tracking down text drawing problems.
  137. •        An alternative is to get various port attributes at the beginning of the
  138. •        update, save them, and then restore them at the end of the update.
  139. */
  140.     RGBForeColor    (&Color_Black);
  141.     TextFont    (systemFont);
  142.     TextSize    (12);
  143.     
  144. /*
  145. •        Now finish up by balancing with a call to EndUpdate(), and restore
  146. •        Quickdraw's pointer to the current Grafport to whatever it was
  147. •        before you updated.
  148. */
  149.  
  150.     EndUpdate    (PeriodicChartDlog);
  151.  
  152.     SetGWorld    (saveCGrafPtr,saveDevice);
  153. }
  154.  
  155.  
  156. /*_____________________________________________________________________________
  157.                         Do_PeriodicChart()- handle an event in the content region
  158.                                             of our Periodic Chart window
  159. _____________________________________________________________________________*/
  160.  
  161.  
  162. void    Do_PeriodicChart    (EventRecord *thisEvent)
  163. {
  164.     long            testKey,keyCode,loop1;
  165. /*
  166. •        We convert the coordinates of the event to local window coordinates, and
  167. •        check to see which element's rectangle, if any, the mousedown was in.
  168. •        If it is a double click, we then open the appropriate element window.
  169. •        Note that handling keyboard events has been broken out into a separate
  170. •        function, Do_Key(), in the file WindowControl.c. In Listing 5 in the
  171. •        original article of Do_PeriodicChart, we handled both mouse and keyboard
  172. •        events in the Do_PeriodicChart function. This resulted in the program
  173. •        inquiring whether an event was a mouse event or keyboard event twice:
  174. •        once in the main event loop, and once in the Do_PeriodicChart function.
  175. •        Handling keyboard events in a separate function is a better arrangement.
  176. */
  177.  
  178.     PeriodicChartWhere    = thisEvent->where;
  179.     GlobalToLocal        (&PeriodicChartWhere);
  180.  
  181.     for    (loop1=1;loop1<=Max_NumElements;loop1++)
  182.     {
  183.         if    (PtInRect(PeriodicChartWhere,&PeriodicRects[loop1])==TRUE)
  184.         {
  185.             if    (WaitDoubleClick(&PeriodicRects[loop1])==Click_Double)    Open_Elements    (loop1);
  186.             return;
  187.         }
  188.     }
  189. }
  190.  
  191.  
  192. /*_____________________________________________________________________________
  193.                         WaitDoubleClick()- detect double clicks vs single clicks
  194. _____________________________________________________________________________*/
  195.  
  196.  
  197. int        WaitDoubleClick    (Rect *inHere)
  198. {
  199.     Point        thisPoint,savePoint;
  200.     EventRecord    thisEvent;
  201.     long        clickTime;
  202. /*
  203. •        As we academics say, commenting this function is left as an exercise
  204. •        for the reader.
  205. */
  206.     while    (EventAvail(mDownMask,&thisEvent)==TRUE)    GetNextEvent(mDownMask,&thisEvent);
  207.  
  208.     while    (StillDown()==TRUE)
  209.     {
  210.         GetMouse        (&thisPoint);
  211.     }
  212.     if    (EventAvail(mUpMask,&thisEvent)==TRUE)    GetNextEvent(mUpMask,&thisEvent);
  213.     savePoint    = thisEvent.where;
  214.     GlobalToLocal    (&savePoint);
  215.     clickTime    = thisEvent.when + GetDblTime();
  216.     while        ((TickCount()<=clickTime)    &&    (EventAvail(mDownMask,&thisEvent)!=TRUE)) {}
  217.     if            (TickCount()>clickTime)
  218.     {
  219.         if    (PtInRect(savePoint,inHere)==TRUE)        return    Click_Single;
  220.         else                                        return    Click_None;
  221.     }
  222.     GetNextEvent(mDownMask,&thisEvent);
  223.     thisPoint    = thisEvent.where;
  224.     GlobalToLocal    (&thisPoint);
  225.     if            (PtInRect(thisPoint,inHere)==TRUE)
  226.     {
  227.         while    (StillDown()==TRUE)    {}
  228.         return    Click_Double;
  229.     }
  230.     return    Click_None;
  231. }
  232.